package com.h.forum.common.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParserBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.SecretKey;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JWTUtil {
    /**
     * 密钥: Base64编码的密钥
     */
    private static final String SECRET = "tBGRS+poX7nrPLCkfHNCNr+lAuGwgsmL1q0yQXJeSow=";

    /**
     * 生成安全密钥：将一个Base64编码的密钥解码并创建一个HMAC SHA密钥。
     */
    private static final Key SECRET_KEY = Keys.hmacShaKeyFor(Decoders.BASE64.decode(SECRET));

    /**
     * 过期时间
     */
    private static final long EXPIRATION = 3 * 24 * 60 * 60 * 1000; // 有效期3天

    /**
     * 获取JWT令牌
     * @param claim
     * @return
     */
    public static String getJwt(Map<String,Object> claim) {
        // 签名算法
        String jwt = Jwts.builder()
                .setClaims(claim)
                .setIssuedAt(new Date()) // 设置签发时间
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION)) // 设置过期时间
                .signWith(SECRET_KEY) // 签名算法
                .compact();
        return jwt;
    }


    /**
     * 验证令牌
     * @param jwt
     * @return
     */
    public static Claims parseJwt(String jwt) {
        if(StringUtil.isEmpty(jwt)) {
            return null;
        }

        // 解析器
        JwtParserBuilder jwtParserBuilder = Jwts.parserBuilder().setSigningKey(SECRET_KEY);
        Claims claims = null;

        try {
            // 解析token
            claims = jwtParserBuilder.build().parseClaimsJws(jwt).getBody();
        }catch (Exception e) {
            // 解析失败
            log.error("解析令牌错误,jwt:{}", jwt, e);
        }

        return claims;
    }


    /**
     * 根据令牌中存储的值，进行获取 Id
     * @param jwt
     * @return
     */
    public static Long getUserIdFromToken(String jwt) {
        Claims claims = JWTUtil.parseJwt(jwt);
        if (claims != null) {
            // 直接从 claims 获取 id，避免不必要的 Map 转换
            Object idValue = claims.get("id");

            if (idValue != null) {
                // 安全地处理不同类型的数字值
                if (idValue instanceof Long) {
                    return (Long) idValue;
                } else if (idValue instanceof Integer) {
                    return ((Integer) idValue).longValue();
                } else if (idValue instanceof String) {
                    return Long.parseLong((String) idValue);
                } else if (idValue instanceof Number) {
                    return ((Number) idValue).longValue();
                }
            }
        }
        return null;
    }
}
